package org.lee.hello;

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.FixedValue;
import net.bytebuddy.implementation.MethodDelegation;
import org.lee.hello.util.ClassUtil;

import java.lang.reflect.Modifier;

/**
 * @author jackielee
 * @version 1.0
 * @description NewClass
 * @date 2021/7/28
 **/
public class NewClass {
    public static void main(String[] args) {

        // 1.only class
        createHelloClass();
        // 2.with main
        createHelloWidthMain();
        // 3.with delegate
        createClassWithDelegate();
    }

    private static void createHelloClass() {
        String className = "HelloByteBuddy";
        DynamicType.Unloaded<?> dynamicType = new ByteBuddy()
                .subclass(Object.class)
                .name("org.lee.hello." + className)
                .make();
        ClassUtil.outputClass(dynamicType.getBytes(), className); // 在target/下产生了HelloByteBuddy.class文件

        /**
         package org.lee.hello;

         public class HelloByteBuddy {
         public HelloByteBuddy() {
         }
         }
         * */
    }

    private static void createHelloWidthMain() {
        String className = "HelloByteBuddyMain";
        DynamicType.Unloaded<?> dynamicType = new ByteBuddy()
                .subclass(Object.class)
                .name("org.lee.hello." + className)
                .defineMethod("main", void.class, Modifier.PUBLIC | Modifier.STATIC) // 可用 | 或 +
                .withParameter(String[].class, "args")
                .intercept(FixedValue.value("Hello dynamic main"))
                .make();
        ClassUtil.outputClass(dynamicType.getBytes(), className); // 在target/下产生了HelloByteBuddyMain.class文件
        /**
         package org.lee.hello;
         public class HelloByteBuddyMain {
         public static void main(String[] args) {
         String var10000 = "Hello dynamic main";
         }

         public HelloByteBuddyMain() {
         }
         }
         */
    }

    private static void createClassWithDelegate() {
        String className = "HelloByteBuddyDelegate";
        DynamicType.Unloaded<?> dynamicType = new ByteBuddy()
                .subclass(Object.class)
                .name("org.lee.hello." + className)
                .defineMethod("main", void.class, Modifier.PUBLIC | Modifier.STATIC)
                .withParameter(String[].class, "args")
                .intercept(MethodDelegation.to(HelloWorld.class))
                .make();
        ClassUtil.outputClass(dynamicType.getBytes(), className); // 在target/下产生了HelloByteBuddyDelegate.class文件

        // 运行
        ClassUtil.runClass(dynamicType);
        /**
         package org.lee.hello;

         public class HelloByteBuddyDelegate {
         public static void main(String[] args) {
         HelloWorld.main(var0);
         }

         public HelloByteBuddyDelegate() {
         }
         }
         */
    }
}
